package com.zgw.fireline.design.edit;

import java.util.ArrayList;
import java.util.Map;

import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.wb.core.model.ObjectInfo;
import org.eclipse.wb.internal.core.model.JavaInfoUtils;
import org.eclipse.wb.internal.core.model.description.MorphingTargetDescription;
import org.eclipse.wb.internal.core.model.property.ComplexProperty;
import org.eclipse.wb.internal.core.model.property.GenericProperty;
import org.eclipse.wb.internal.core.model.property.JavaProperty;
import org.eclipse.wb.internal.core.model.property.Property;
import org.eclipse.wb.internal.core.model.property.converter.StringArrayConverter;
import org.eclipse.wb.internal.core.model.property.converter.StringConverter;
import org.eclipse.wb.internal.core.model.property.editor.AbstractTextPropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.presentation.ButtonPropertyEditorPresentation;
import org.eclipse.wb.internal.core.model.property.editor.presentation.PropertyEditorPresentation;
import org.eclipse.wb.internal.core.model.property.table.PropertyTable;
import org.eclipse.wb.internal.core.model.variable.VariableSupport;
import org.eclipse.wb.internal.core.utils.ast.AstEditor;
import org.eclipse.wb.internal.core.utils.ast.StatementTarget;
import org.eclipse.wb.internal.core.utils.execution.ExecutionUtils;
import org.eclipse.wb.internal.core.utils.execution.RunnableEx;
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;

import com.zgw.fireline.design.Model.DatasetCodeUtil;
import com.zgw.fireline.design.Model.DatasetInfo;
import com.zgw.fireline.design.Model.MorphingSupport;

/**
 * 数据源管理属性 编辑器
 * */
public class SourceManagerPropertyEditor extends AbstractTextPropertyEditor {

	public SourceManagerPropertyEditor() {

	}

	// //////////////////////////////////////////////////////////////////////////
	//
	// Presentation
	//
	// //////////////////////////////////////////////////////////////////////////
	private final PropertyEditorPresentation m_presentation = new ButtonPropertyEditorPresentation() {
		@Override
		protected void onClick(PropertyTable propertyTable, Property property)
				throws Exception {
			openDialog(propertyTable, property);
		}
	};

	@Override
	public final PropertyEditorPresentation getPresentation() {
		return m_presentation;
	}

	@Override
	public boolean activate(PropertyTable propertyTable, Property property,
			Point location) throws Exception {
		return false;
	}

	// 打开Dataset 资源管理窗口
	protected void openDialog(final PropertyTable propertyTable,
			Property property) throws Exception {
		if (property instanceof JavaProperty) {
			JavaProperty gp = (JavaProperty) property;
			final DatasetInfo dataset = (DatasetInfo) gp.getJavaInfo();
			final DataSourceDialog dlg = new DataSourceDialog(Display
					.getDefault().getActiveShell(), SWT.NONE, dataset);
			if (dlg.open() == DataSourceDialog.OK) {
				ExecutionUtils.run(dataset.getParent(), new RunnableEx() {
					public void run() throws Exception {
						DatasetInfo new_data = updateConstructor(dataset, dlg);
						updateParams(new_data, dlg);
						updateKeyColumns(new_data, dlg);
						updateLoadType(new_data, dlg);
					}
				});

			}

		}
	}

	// 修改加载方式
	protected void updateLoadType(DatasetInfo data, DataSourceDialog dlg)
			throws Exception {
		String sign = ReflectionUtils.getMethodSignature("update");
		data.removeMethodInvocations(sign);
		if (dlg.loadType == 0) {

		} else if (dlg.loadType == 1) {

		} else if (dlg.loadType == 2) { // 界面创建之前更新
			MethodDeclaration method = DatasetCodeUtil
					.buildCreateGUIBeforeMethod(data.getRootJava());
			StatementTarget target = new StatementTarget(method, false);
			data.addMethodInvocation(target, sign, "");
		} else if (dlg.loadType == 3) {// 界面创建之后更新
			MethodDeclaration method = DatasetCodeUtil
					.buildCreateGUIAfterMethod(data.getRootJava());
			StatementTarget target = new StatementTarget(method, false);
			data.addMethodInvocation(target, sign, "");
		}
	}

	// 修改主键列信息
	protected void updateKeyColumns(DatasetInfo data, DataSourceDialog dlg)
			throws Exception {
		GenericProperty p = (GenericProperty) data
				.getPropertyByTitle("keyColumns");
		String[] keys = dlg.keyList.toArray(new String[dlg.keyList.size()]);
		if (p.getValue() != null) {
			p.setValue(keys);
		} else {
			String source = StringArrayConverter.INSTANCE.toJavaSource(data,
					keys);
			StatementTarget target = DatasetCodeUtil.getFistWidgetTarget(data
					.getRootJava());
			String signature = ReflectionUtils.getMethodSignature(
					"setKeyColumns", String[].class);
			data.addMethodInvocation(target, signature, source);
		}
	}

	/*
	 * 修改构造函数属性
	 */
	private DatasetInfo updateConstructor(DatasetInfo dataset,
			final DataSourceDialog dlg) throws Exception {
		final AstEditor editor = dataset.getEditor();
		final TypeDeclaration typeDeclaration = JavaInfoUtils
				.getTypeDeclaration(dataset.getRootJava());
		if (dlg.isSysSource != dataset.isSysSource()) {
			MorphingTargetDescription target = new MorphingTargetDescription(
					dataset.getDescription().getComponentClass(),
					dlg.isSysSource ? "sys" : "custom");
			dataset = (DatasetInfo) MorphingSupport.morph(
					"com.zgw.fireline.base.dataset.Dataset", dataset, target);
			// 选中当前模型
			ArrayList<ObjectInfo> objects = new ArrayList<ObjectInfo>();
			objects.add(dataset);
			dataset.getRoot().getBroadcastObject().select(objects);
		}

		// 取构造函数属性
		ComplexProperty constructor = (ComplexProperty) dataset
				.getPropertyByTitle("Constructor");
		Property[] params = constructor.getProperties();
		if (dlg.isSysSource) {
			// 设置系统资源编码
			((GenericProperty) params[1]).setExpression("\"" + dlg.defineKey
					+ "\"", Property.UNKNOWN_VALUE);
			// 设置资源提供器
			String provide = DatasetCodeUtil.prepareDBInvokeSource(
					dlg.baseProvideClass, typeDeclaration, editor);
			((GenericProperty) params[2]).setExpression(provide,
					Property.UNKNOWN_VALUE);
		} else {
			// 设置SQL命令语句
			// ((GenericProperty) params[0]).setExpression("\"" + dlg.sqlCommand
			// + "\"", Property.UNKNOWN_VALUE);
			((GenericProperty) params[0]).setValue(dlg.sqlCommand);
			// 设置资源提供器
			String source = DatasetCodeUtil.prepareDBInvokeSource(
					dlg.baseProvideClass, typeDeclaration, editor);
			((GenericProperty) params[1]).setExpression(source,
					Property.UNKNOWN_VALUE);
		}
		return dataset;
	}

	/*
	 * 修改参数值
	 */
	private void updateParams(DatasetInfo dataset, DataSourceDialog dlg)
			throws Exception {
		String signature = ReflectionUtils.getMethodSignature("setParam",
				new Class[] { int.class, Object.class });
		dataset.removeMethodInvocations(signature); // 移除原来的 参数设置
		MethodDeclaration setParamMethod = DatasetCodeUtil
				.buildSetParamsContext(dataset.getRootJava());
		StatementTarget target = new StatementTarget(setParamMethod, false);
		// 添加新的参数设置
		for (Map.Entry<Integer, Object> p : dlg.params.entrySet()) {
			int index = p.getKey();
			String value = null;
			if (p.getValue() instanceof String) {
				value = StringConverter.INSTANCE.toJavaSource(dataset,
						p.getValue());
			} else if (p.getValue() instanceof Param) {
				Param param = (Param) p.getValue();
				if (param.target != null) {
					if (param.target.isRoot()) {
						value = "this." + param.signature;
					} else {
						VariableSupport var = param.target.getVariableSupport();
						if (var.canConvertLocalToField()) {
							var.convertLocalToField();
						}
						value = var.getName() + "." + param.signature;
					}
				}
			}
			if (value != null) {
				dataset.addMethodInvocation(target, signature, index + ","
						+ value);
			}
		}
	}

	@Override
	protected String getText(Property property) throws Exception {
		return null;
	}

	@Override
	protected String getEditorText(Property property) throws Exception {
		return null;
	}

	@Override
	protected boolean setEditorText(Property property, String text)
			throws Exception {
		return false;
	}

}
